﻿#if _TOOLKIT2_5 || _TOOLKIT3
using System;
using System.Collections;
#if _TOOLKIT3
using System.Collections.Generic;
#endif
using System.Diagnostics;
using System.Reflection;
using System.Web;
using Org.EasyWeb.Data;
using Org.EasyWeb.SysUtil;

namespace Org.EasyWeb.Sys
{
    internal class WebAppInitialization
    {
#if _TOOLKIT3
        private List<AppData> fInitializations;
#endif
#if _TOOLKIT2_5 
        private ArrayList fInitializations;
#endif
#if _TOOLKIT3
        internal class AppData : IComparable<AppData>
#endif
#if _TOOLKIT2_5
        internal class AppData : IComparable
#endif
        {
            public ToolkitInitAttribute Attribute;
            public Assembly Assembly;
            public IInitialization Initialization;

            /// <summary>
            /// Creates a new instance of AppData
            /// </summary>
            /// <param name="attribute"></param>
            /// <param name="assembly"></param>
            public AppData(ToolkitInitAttribute attribute, Assembly assembly)
            {
                Attribute = attribute;
                Assembly = assembly;

                Type initType = assembly.GetType(attribute.InitClass);
                Initialization = (IInitialization)Activator.CreateInstance(initType);
            }

#if _TOOLKIT2_5
            #region IComparable 成员

            public int CompareTo(object obj)
            {
                int thisOrder = (int)this.Attribute.Priority;
                int otherOrder = (int)((AppData)obj).Attribute.Priority;

                if (thisOrder > otherOrder)
                    return 1;
                else if (thisOrder == otherOrder)
                    return 0;
                else
                    return -1;
            }

            #endregion
#endif

#if _TOOLKIT3
            #region IComparable<AppData> 成员

           public int CompareTo(AppData other)
           {
               int thisOrder = (int)this.Attribute.Priority;
               int otherOrder = (int)other.Attribute.Priority;

               if (thisOrder > otherOrder)
                   return 1;
               else if (thisOrder == otherOrder)
                   return 0;
               else
                   return -1;
           }

            #endregion
#endif
        }
        /// <summary>
        /// Creates a new instance of WebAppInitialization
        /// </summary>
        public WebAppInitialization()
        {
#if _TOOLKIT3
            fInitializations = new List<AppData>();
#endif
#if _TOOLKIT2_5  
            fInitializations = new ArrayList();
#endif
        }

        public void Initialize(BinAssemblyData binAssembly)
        {
            Type attType = typeof(ToolkitInitAttribute);
            foreach (Assembly ass in binAssembly.BinAssemblies)
            {
                ToolkitInitAttribute att = (ToolkitInitAttribute)
                    Attribute.GetCustomAttribute(ass, attType);
                if (att != null)
                {
                    try
                    {
                        fInitializations.Add(new AppData(att, ass));
                    }
                    catch (System.Exception ex)
                    {
                        Trace.WriteLine(ex.Message, StringUtil.TK_ERROR);
                    }
                }
            }
            fInitializations.Sort();
        }

        public void ApplicationStart(HttpApplication application, IAppGlobal global)
        {
            foreach (AppData data in fInitializations)
            {
                try
                {
                    data.Initialization.ApplicationStart(application, global);
                }
                catch (System.Exception ex)
                {
                    Trace.WriteLine(ex.Message, StringUtil.TK_ERROR);
                }
            }
        }

        public void SessionStart(HttpApplication application, ISessionGlobal global)
        {
            foreach (AppData data in fInitializations)
                try
                {
                    data.Initialization.SessionStart(application, global);
                }
                catch (System.Exception ex)
                {
                    Trace.WriteLine(ex.Message, StringUtil.TK_ERROR);
                }
        }

        public void ApplicationEnd(HttpApplication application)
        {
            foreach (AppData data in fInitializations)
                try
                {
                    data.Initialization.ApplicationEnd(application);
                }
                catch (System.Exception ex)
                {
                    Trace.WriteLine(ex.Message, StringUtil.TK_ERROR);
                }
        }

        public void SessionEnd(HttpApplication application)
        {
            foreach (AppData data in fInitializations)
                try
                {
                    data.Initialization.SessionEnd(application);
                }
                catch (System.Exception ex)
                {
                    Trace.WriteLine(ex.Message, StringUtil.TK_ERROR);
                }
        }
    }
}
#endif